package com.huilian.iotbox.data.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.huilian.iotbox.data.dao.CommodityStockRecordCommonDao;
import com.huilian.iotbox.data.dto.*;
import com.huilian.iotbox.data.enums.CommodityStockRecordFirstTypeEnum;
import com.huilian.iotbox.data.enums.CommodityStockRecordSecondTypeEnum;
import com.huilian.iotbox.data.service.*;
import com.huilian.iotbox.data.utils.Util;
import com.huilian.iotbox.data.vo.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;

@Service
public class CommodityStockRecordCommonServiceImpl implements CommodityStockRecordCommonService {
    @Resource
    private MerchantStoreCommonService merchantStoreService;
    @Resource
    private CommodityStockRecordItemCommonService commodityStockRecordItemService;
    @Resource
    private CommodityStockCommonService commodityStockService;
    @Resource
    private CommodityStockItemCommonService commodityStockItemService;
    @Resource
    private CommoditySupplierCommonService commoditySupplierService;
    @Autowired
    private CommodityStockRecordCommonDao commodityStockRecordDao;
    @Override
    public int add(CommodityStockRecordDto commodityStockRecordDto) {
        return commodityStockRecordDao.add(commodityStockRecordDto);
    }

    @Override
    public PageInfo<CommodityStockRecordVo> findStockRecord(CommodityStockRecordDto commodityStockRecordDto) throws Exception {
        commodityStockRecordDto.setGroupType(2);
        PageHelper.orderBy("csr.createTime DESC");
        PageHelper.startPage(commodityStockRecordDto.getPageNum(), commodityStockRecordDto.getPageSize(), true);
        List<CommodityStockRecordVo> list = commodityStockRecordDao.findStockRecord(commodityStockRecordDto);
        for (CommodityStockRecordVo commodityStockRecordVo : list) {
            Integer quantity = 0;
            BigDecimal costPrice = BigDecimal.ZERO;
            BigDecimal retailPrice = BigDecimal.ZERO;
            for (CommodityStockRecordItemVo commodityStockRecordItemVo : commodityStockRecordVo.getCommodityStockRecordItemVoList()) {
                quantity += commodityStockRecordItemVo.getQuantity();
                costPrice = costPrice.add(commodityStockRecordItemVo.getCostPrice());
                retailPrice = retailPrice.add(commodityStockRecordItemVo.getRetailPrice());
                if (ObjectUtils.isEmpty(commodityStockRecordItemVo.getType())) {
                    throw new Exception("商品不存在");
                }
            }
            commodityStockRecordVo.setQuantity(quantity);
            commodityStockRecordVo.setCostPrice(costPrice);
            commodityStockRecordVo.setRetailPrice(retailPrice);
        }
        return new PageInfo<>(list);
    }

    @Override
    public List<CommodityStockRecordVo> findStockRecordData(CommodityStockRecordDto commodityStockRecordDto) {
        commodityStockRecordDto.setGroupType(2);
        List<CommodityStockRecordVo> list = commodityStockRecordDao.findStockRecord(commodityStockRecordDto);
        return commodityStockRecordDao.findStockRecord(commodityStockRecordDto);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void intoRecord(CommodityStockRecordDto commodityStockRecordDto) throws Exception {
        if (commodityStockRecordDto.getDisplayRackItemDtos().isEmpty()) {
            throw new Exception("请输入入库信息");
        }
        CommodityStockRecordDto addCommodityStockRecordDto = new CommodityStockRecordDto();
        addCommodityStockRecordDto.setUserId(commodityStockRecordDto.getUserInfo().getId());
        addCommodityStockRecordDto.setMerchantStoreId(commodityStockRecordDto.getMerchantStoreId());
        addCommodityStockRecordDto.setOutTradeNo(Util.getOutTradeNo());
        addCommodityStockRecordDto.setInDisplayRackId(commodityStockRecordDto.getDisplayRackId());
        addCommodityStockRecordDto.setFirstType(commodityStockRecordDto.getFirstType());
        addCommodityStockRecordDto.setSecondaryType(CommodityStockRecordSecondTypeEnum.MANUAL_INTO.getCode());//手动入库
        addCommodityStockRecordDto.setDescription(ObjectUtils.isEmpty(commodityStockRecordDto.getDescription()) ? "手动入库" : commodityStockRecordDto.getDescription());

        addCommodityStockRecordDto.setOperationUserId(commodityStockRecordDto.getUserInfo().getId());
        int resultV3 = commodityStockRecordDao.add(addCommodityStockRecordDto);
        for (CommodityDto dto : commodityStockRecordDto.getDisplayRackItemDtos()) {
//            if (ObjectUtils.isEmpty(dto.getCommoditySupplierId())) {
//                throw new Exception("请为该场地添加供应商后继续操作");
//            }

            CommodityStockRecordItemDto commodityStockRecordItemDto = new CommodityStockRecordItemDto();
            commodityStockRecordItemDto.setCommodityStockRecordId(addCommodityStockRecordDto.getId());
            commodityStockRecordItemDto.setCommodityId(dto.getId());
            commodityStockRecordItemDto.setQuantity(dto.getEtStock());
            commodityStockRecordItemDto.setCommoditySupplierId(dto.getCommoditySupplierId());
            commodityStockRecordItemDto.setCostPrice((dto.getEtCostPrice().compareTo(BigDecimal.ZERO) == 0 ? dto.getCostPrice() : dto.getEtCostPrice()).multiply(BigDecimal.valueOf(dto.getEtStock())));
            commodityStockRecordItemDto.setRetailPrice((dto.getEtRetailPrice().compareTo(BigDecimal.ZERO) == 0 ? dto.getRetailPrice() : dto.getEtRetailPrice()).multiply(BigDecimal.valueOf(dto.getEtStock())));
            commodityStockRecordItemDto.setStockBefore(dto.getStock());
            commodityStockRecordItemDto.setStockAfter(dto.getEtStock() + dto.getStock());
            commodityStockRecordItemDto.setCostPriceBefore(dto.getCostPrice());
            commodityStockRecordItemDto.setCostPriceAfter(dto.getEtCostPrice().compareTo(BigDecimal.ZERO) == 0 ? dto.getCostPrice() : dto.getEtCostPrice());
            commodityStockRecordItemDto.setRetailPriceBefore(dto.getRetailPrice());
            commodityStockRecordItemDto.setRetailPriceAfter(dto.getEtRetailPrice().compareTo(BigDecimal.ZERO) == 0 ? dto.getRetailPrice() : dto.getEtRetailPrice());
            commodityStockRecordItemDto.setRemark(ObjectUtils.isEmpty(dto.getRemark()) ? "手动入库" : dto.getRemark());

            int resultV4 = commodityStockRecordItemService.add(commodityStockRecordItemDto);

            dto.setStock(dto.getEtStock());
            dto.setCostPrice(dto.getEtCostPrice().compareTo(BigDecimal.ZERO) == 0 ? dto.getCostPrice() : dto.getEtCostPrice());
            dto.setRetailPrice(dto.getEtRetailPrice().compareTo(BigDecimal.ZERO) == 0 ? dto.getRetailPrice() : dto.getEtRetailPrice());

            CommodityStockDto commodityStockDto = new CommodityStockDto();
            commodityStockDto.setCommodityId(dto.getId());
            commodityStockDto.setMerchantStoreId(commodityStockRecordDto.getMerchantStoreId());
            commodityStockDto.setAddStock(dto.getStock());
            commodityStockDto.setAddCostPrice(dto.getCostPrice());
            commodityStockDto.setAddRetailPrice(dto.getRetailPrice());
            commodityStockDto.setUserId(commodityStockRecordDto.getUserInfo().getMchStoreUserId());
            commodityStockDto.setUserInfo(commodityStockRecordDto.getUserInfo());

            CommodityStockVo commodityStockVo = commodityStockService.findCommodityStock(commodityStockDto);
            if (ObjectUtils.isEmpty(commodityStockVo)) {
                commodityStockDto.setStock(0);
                commodityStockDto.setCostPrice(BigDecimal.ZERO);
                commodityStockDto.setRetailPrice(BigDecimal.ZERO);
                commodityStockDto.setSafeStock(0);
                commodityStockDto.setVersion(0);
                commodityStockService.add(commodityStockDto);
            }
            int resultV5 = commodityStockService.updateAmendStockByCommodityIdAdd(commodityStockDto);

            CommodityStockItemDto commodityStockItemDto = new CommodityStockItemDto();
            commodityStockItemDto.setCommoditySupplierId(dto.getCommoditySupplierId());
            commodityStockItemDto.setCommodityStockId(!ObjectUtils.isEmpty(commodityStockDto.getId()) ? commodityStockDto.getId() : commodityStockVo.getId());
            commodityStockItemDto.setCostPrice(dto.getCostPrice());
            CommodityStockItemVo commodityStockItemVo = commodityStockItemService.findCommoditySupplierId(commodityStockItemDto);
            if (ObjectUtils.isEmpty(commodityStockItemVo)) {
                commodityStockItemService.add(commodityStockItemDto);
            } else {
                commodityStockItemDto.setId(commodityStockItemVo.getId());
                commodityStockItemService.updateCostPrice(commodityStockItemDto);
            }

            if (!ObjectUtils.isEmpty(dto.getCommoditySupplierId())) {
                CommoditySupplierDto commoditySupplierDto = new CommoditySupplierDto();
                CommoditySupplierVo commoditySupplierVo = commoditySupplierService.getSupplierById(dto.getCommoditySupplierId());
                commoditySupplierDto.setId(commoditySupplierVo.getId());
                commoditySupplierDto.setVersion(commoditySupplierVo.getVersion());
                Integer purchaseQuantity = commoditySupplierVo.getPurchaseQuantity() + dto.getStock();
                BigDecimal purchaseAmount = commoditySupplierVo.getPurchaseAmount().add(dto.getCostPrice().multiply(BigDecimal.valueOf(dto.getStock())));
                commoditySupplierDto.setPurchaseQuantity(purchaseQuantity);
                commoditySupplierDto.setPurchaseAmount(purchaseAmount);
                int resultV6 = commoditySupplierService.updatePurchase(commoditySupplierDto);

            }

            if (resultV3 < 1 || resultV4 < 1 || resultV5 < 1) {
                throw new Exception("生成入库单失败");
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void outRecord(CommodityStockRecordDto commodityStockRecordDto) throws Exception {
        if (commodityStockRecordDto.getDisplayRackItemDtos().isEmpty()) {
            throw new Exception("请输入出库信息");
        }
        CommodityStockRecordDto addCommodityStockRecordDto = new CommodityStockRecordDto();
        addCommodityStockRecordDto.setUserId(commodityStockRecordDto.getUserInfo().getId());
        addCommodityStockRecordDto.setMerchantStoreId(commodityStockRecordDto.getMerchantStoreId());
        addCommodityStockRecordDto.setOutTradeNo(Util.getOutTradeNo());
        addCommodityStockRecordDto.setOutDisplayRackId(commodityStockRecordDto.getDisplayRackId());
        addCommodityStockRecordDto.setFirstType(commodityStockRecordDto.getFirstType());
        addCommodityStockRecordDto.setSecondaryType(CommodityStockRecordSecondTypeEnum.MANUAL_OUT.getCode());//手动出库
        addCommodityStockRecordDto.setDescription(ObjectUtils.isEmpty(commodityStockRecordDto.getDescription()) ? "手动出库" : commodityStockRecordDto.getDescription());

        addCommodityStockRecordDto.setOperationUserId(commodityStockRecordDto.getUserInfo().getId());
        int resultV3 = commodityStockRecordDao.add(addCommodityStockRecordDto);

        for (CommodityDto dto : commodityStockRecordDto.getDisplayRackItemDtos()) {
            CommodityStockRecordItemDto commodityStockRecordItemDto = new CommodityStockRecordItemDto();
            commodityStockRecordItemDto.setCommodityStockRecordId(addCommodityStockRecordDto.getId());
            commodityStockRecordItemDto.setCommodityId(dto.getId());
            commodityStockRecordItemDto.setQuantity(dto.getEtStock());
            commodityStockRecordItemDto.setCommoditySupplierId(dto.getCommoditySupplierId());
            commodityStockRecordItemDto.setCostPrice(dto.getCostPrice().multiply(BigDecimal.valueOf(dto.getEtStock())));
            commodityStockRecordItemDto.setRetailPrice(dto.getRetailPrice().multiply(BigDecimal.valueOf(dto.getEtStock())));
            commodityStockRecordItemDto.setStockBefore(dto.getStock());
            commodityStockRecordItemDto.setStockAfter(dto.getStock() - dto.getEtStock());
            commodityStockRecordItemDto.setCostPriceBefore(dto.getCostPrice());
            commodityStockRecordItemDto.setCostPriceAfter(dto.getCostPrice());
            commodityStockRecordItemDto.setRetailPriceBefore(dto.getRetailPrice());
            commodityStockRecordItemDto.setRetailPriceAfter(dto.getRetailPrice());
            commodityStockRecordItemDto.setRemark(ObjectUtils.isEmpty(dto.getRemark()) ? "手动出库" : dto.getRemark());


            int resultV4 = commodityStockRecordItemService.add(commodityStockRecordItemDto);

            dto.setStock(dto.getEtStock());

            CommodityStockDto commodityStockDto = new CommodityStockDto();
            commodityStockDto.setCommodityId(dto.getId());
            commodityStockDto.setMerchantStoreId(commodityStockRecordDto.getMerchantStoreId());
            commodityStockDto.setUserId(commodityStockRecordDto.getUserInfo().getId());
            commodityStockDto.setAddStock(dto.getStock());
            commodityStockDto.setAddCostPrice(dto.getCostPrice());
            commodityStockDto.setAddRetailPrice(dto.getRetailPrice());
            commodityStockDto.setUserInfo(commodityStockRecordDto.getUserInfo());

            CommodityStockVo commodityStockVo = commodityStockService.findCommodityStock(commodityStockDto);
            if (ObjectUtils.isEmpty(commodityStockVo)) {
                commodityStockDto.setStock(0);
                commodityStockDto.setCostPrice(BigDecimal.ZERO);
                commodityStockDto.setRetailPrice(BigDecimal.ZERO);
                commodityStockDto.setSafeStock(0);
                commodityStockDto.setVersion(0);
                commodityStockService.add(commodityStockDto);
            }
            int resultV5 = commodityStockService.updateAmendStockByCommodityIdMinus(commodityStockDto);
            if (resultV3 < 1 || resultV4 < 1 || resultV5 < 1) {
                throw new Exception("生成出库单失败");
            }
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void returnRecord(CommodityStockRecordDto commodityStockRecordDto) throws Exception {
        if (commodityStockRecordDto.getDisplayRackItemDtos().isEmpty()) {
            throw new Exception("请输入出库信息");
        }
        CommodityStockRecordDto addCommodityStockRecordDto = new CommodityStockRecordDto();
        addCommodityStockRecordDto.setUserId(commodityStockRecordDto.getUserInfo().getId());
        addCommodityStockRecordDto.setMerchantStoreId(commodityStockRecordDto.getMerchantStoreId());
        addCommodityStockRecordDto.setOutTradeNo(Util.getOutTradeNo());
        if (commodityStockRecordDto.getFirstType().equals(CommodityStockRecordFirstTypeEnum.RETURN_OF_GOODS.getCode())) {
            addCommodityStockRecordDto.setOutDisplayRackId(commodityStockRecordDto.getDisplayRackId());
            addCommodityStockRecordDto.setInDisplayRackId(commodityStockRecordDto.getDisplayRackId());
        }
        addCommodityStockRecordDto.setFirstType(commodityStockRecordDto.getFirstType());
        addCommodityStockRecordDto.setSecondaryType(CommodityStockRecordSecondTypeEnum.RETURN.getCode());//销售退款
        addCommodityStockRecordDto.setDescription(ObjectUtils.isEmpty(commodityStockRecordDto.getDescription()) ? "库存退货" : commodityStockRecordDto.getDescription());
        addCommodityStockRecordDto.setOperationUserId(commodityStockRecordDto.getUserInfo().getId());
        int resultV3 = commodityStockRecordDao.add(addCommodityStockRecordDto);
        for (CommodityDto dto : commodityStockRecordDto.getDisplayRackItemDtos()) {
            CommodityStockRecordItemDto commodityStockRecordItemDto = new CommodityStockRecordItemDto();
            commodityStockRecordItemDto.setCommodityStockRecordId(addCommodityStockRecordDto.getId());
            commodityStockRecordItemDto.setCommodityId(dto.getId());
            commodityStockRecordItemDto.setQuantity(dto.getEtStock());
            commodityStockRecordItemDto.setCommoditySupplierId(dto.getCommoditySupplierId());
            commodityStockRecordItemDto.setCostPrice(dto.getCostPrice().multiply(BigDecimal.valueOf(dto.getEtStock())));
            commodityStockRecordItemDto.setRetailPrice(dto.getRetailPrice().multiply(BigDecimal.valueOf(dto.getEtStock())));
            commodityStockRecordItemDto.setStockBefore(dto.getStock());
            commodityStockRecordItemDto.setStockAfter(dto.getStock() + dto.getEtStock());
            commodityStockRecordItemDto.setCostPriceBefore(dto.getCostPrice());
            commodityStockRecordItemDto.setCostPriceAfter(dto.getCostPrice());
            commodityStockRecordItemDto.setRetailPriceBefore(dto.getRetailPrice());
            commodityStockRecordItemDto.setRetailPriceAfter(dto.getRetailPrice());
            commodityStockRecordItemDto.setRemark(ObjectUtils.isEmpty(dto.getRemark()) ? "销售退货" : dto.getRemark());


            int resultV4 = commodityStockRecordItemService.add(commodityStockRecordItemDto);

            dto.setStock(dto.getEtStock());

            CommodityStockDto commodityStockDto = new CommodityStockDto();
            commodityStockDto.setCommodityId(dto.getId());
            commodityStockDto.setMerchantStoreId(commodityStockRecordDto.getMerchantStoreId());
            commodityStockDto.setCommoditySupplierId(dto.getCommoditySupplierId());
            commodityStockDto.setAddStock(dto.getStock());
            commodityStockDto.setAddCostPrice(dto.getCostPrice());
            commodityStockDto.setAddRetailPrice(dto.getRetailPrice());
            commodityStockDto.setUserInfo(commodityStockRecordDto.getUserInfo());

            CommodityStockVo commodityStockVo = commodityStockService.findCommodityStock(commodityStockDto);
            if (ObjectUtils.isEmpty(commodityStockVo)) {
                commodityStockDto.setStock(0);
                commodityStockDto.setCostPrice(BigDecimal.ZERO);
                commodityStockDto.setRetailPrice(BigDecimal.ZERO);
                commodityStockDto.setSafeStock(0);
                commodityStockDto.setVersion(0);
                commodityStockService.add(commodityStockDto);
            }
            int resultV5 = commodityStockService.updateAmendStockByCommodityIdAdd(commodityStockDto);

            if (resultV3 < 1 || resultV4 < 1 || resultV5 < 1) {
                throw new Exception("生成出库单失败，请检查填写数据是否正确");
            }
        }
    }

    @Override
    public PageInfo<CommodityStockRecordVo> findInventory(CommodityStockRecordDto commodityStockRecordDto) {
        PageHelper.startPage(commodityStockRecordDto.getPageNum(), commodityStockRecordDto.getPageSize());
        commodityStockRecordDto.setFirstType(CommodityStockRecordFirstTypeEnum.INVENTORY_SHEET.getCode());
        commodityStockRecordDto.setSecondaryType(CommodityStockRecordSecondTypeEnum.COMMODITY_INVENTORY.getCode());

        List<CommodityStockRecordVo> commodityStockRecordVoList = commodityStockRecordDao.findStockRecord(commodityStockRecordDto);

        for (CommodityStockRecordVo commodityStockRecordVo : commodityStockRecordVoList) {
            int totalStockBefore = 0;
            int totalStockAfter = 0;
            int totalDifference = 0;
            BigDecimal totalDifferenceCostPrice = BigDecimal.ZERO;
            BigDecimal totalDifferenceRetailPrice = BigDecimal.ZERO;

            for (CommodityStockRecordItemVo commodityStockRecordItemVo : commodityStockRecordVo.getCommodityStockRecordItemVoList()) {
                totalStockBefore += commodityStockRecordItemVo.getStockBefore();
                totalStockAfter += commodityStockRecordItemVo.getStockAfter();

                int difference = commodityStockRecordItemVo.getStockAfter() - commodityStockRecordItemVo.getStockBefore();
                BigDecimal differenceCostPrice = commodityStockRecordItemVo.getCostPrice().multiply(BigDecimal.valueOf(difference));
                BigDecimal differenceRetailPrice = commodityStockRecordItemVo.getRetailPrice().multiply(BigDecimal.valueOf(difference));

                commodityStockRecordItemVo.setDifference(difference);
                commodityStockRecordItemVo.setDifferenceCostPrice(differenceCostPrice);
                commodityStockRecordItemVo.setDifferenceRetailPrice(differenceRetailPrice);

                totalDifference += difference;
                totalDifferenceCostPrice = totalDifferenceCostPrice.add(differenceCostPrice);
                totalDifferenceRetailPrice = totalDifferenceRetailPrice.add(differenceRetailPrice);
            }

            commodityStockRecordVo.setTotalStockBefore(totalStockBefore);
            commodityStockRecordVo.setTotalStockAfter(totalStockAfter);
            commodityStockRecordVo.setTotalDifference(totalDifference);
            commodityStockRecordVo.setTotalDifferenceCostPrice(totalDifferenceCostPrice);
            commodityStockRecordVo.setTotalDifferenceRetailPrice(totalDifferenceRetailPrice);
        }

        return new PageInfo<>(commodityStockRecordVoList);
    }
}
